package com.jimei.voucher.common;

import java.util.List;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

/**
 * redis操作工具
 */
@Component
public class RedisOps {
    
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 
     * @param key
     * @param value
     */
    public void set(String key, String value) {
        stringRedisTemplate.opsForValue().set(key, value);
    }
    
    /**
     * 
     * @param key
     * @param value
     * @param timeout 超时时间(秒)
     */
    public void set(String key, String value, long timeout) {
        stringRedisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
    }
    
    /**
     * 
     * @param key
     * @return
     */
    public String get(String key) {
        return stringRedisTemplate.opsForValue().get(key);
    }
    
    /**
     * 
     * @param key
     * @param timeout 超时时间(秒)
     * @return
     */
    public Boolean expire(String key, long timeout) {
        return stringRedisTemplate.expire(key, timeout, TimeUnit.SECONDS);
    }
    
    /**
     * 将一个或多个值 value 插入到列表 key 的表头
     * @param key
     * @param value
     * @return 
     */
    public Long lPush(String key, String... value) {
        return stringRedisTemplate.opsForList().leftPushAll(key, value);
    }
    
    /**
     * 移除并返回列表 key 的尾元素
     * @param key
     * @return 
     */
    public String rPop(String key) {
        return stringRedisTemplate.opsForList().rightPop(key);
    }
    
    /**
     * 返回列表 key 的长度
     * @param key
     * @return
     */
    public Long lLen(String key) {
        return stringRedisTemplate.opsForList().size(key);
    }
    
    /**
     * 返回列表 key 中指定区间内的元素
     * @param key
     * @param start
     * @param end
     * @return
     */
    public List<String> lRange(String key, long start, long end){
        return stringRedisTemplate.opsForList().range(key, start, end);
    }
    
    /**
     * 将 key 中储存的数字值增一
     * @param key
     * @return 执行++之后的value
     */
    public Long incr(String key) {
        byte[] rowKey = stringRedisTemplate.getStringSerializer().serialize(key);
        return stringRedisTemplate.execute(new RedisCallback<Long>() {

            @Override
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                return connection.incr(rowKey);
            }
            
        });
    }
    
    /**
     * 将 key 中储存的数字值减一
     * @param key
     * @return 执行--之后的value
     */
    public Long decr(String key) {
        byte[] rowKey = stringRedisTemplate.getStringSerializer().serialize(key);
        return stringRedisTemplate.execute(new RedisCallback<Long>() {

            @Override
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                return connection.decr(rowKey);
            }
            
        });
    }
    
    /**
     * 将 key 的值设为 value ，当且仅当 key 不存在。
     * @param key
     * @param value
     * @return
     */
    public Boolean setNX(String key, String value) {
        return stringRedisTemplate.opsForValue().setIfAbsent(key, value);
    }
}
